home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / space / software / unix / xanim / xanim_fl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-04  |  20.1 KB  |  793 lines

  1.  
  2. /*
  3.  * xanim_fli.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed
  9.  * without fee provided that this copyright notice is preserved 
  10.  * intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim.h"
  19. #include "xanim_fli.h" 
  20.  
  21. void Read_Fli_Header();
  22. void Read_Fli_Frame_Header();
  23. void Fli_Read_File();
  24. void Decode_Fli_BRUN();
  25. void Decode_Fli_LC();
  26. void Decode_Fli_LC7();
  27. void Read_Fli_COLOR();
  28. ULONG UTIL_Get_LSB_Long();
  29. ULONG UTIL_Get_LSB_Short();
  30.  
  31. void ACT_Setup_CMAP();
  32. void ACT_Get_Next_Action();
  33. void UTIL_Sub_Image();
  34.  
  35. static ColorReg fli_cmap[FLI_MAX_COLORS];
  36. static Fli_Header fli_hdr;
  37. static Fli_Frame_Header frame_hdr;
  38.  
  39. /*
  40.  *
  41.  */
  42. int Is_FLI_File(filename)
  43. char *filename;
  44. {
  45.   FILE *fin;
  46.   ULONG data;
  47.  
  48.   if ( (fin=fopen(filename,"r")) == 0)
  49.   {
  50.    fprintf(stderr,"can't open %s\n",filename);
  51.    TheEnd();
  52.   }
  53.  
  54.   data = UTIL_Get_LSB_Long(fin);  /* read past size */
  55.   data = UTIL_Get_LSB_Short(fin); /* read magic */
  56.   fclose(fin);
  57.   if ( (data == 0xaf11) || (data == 0xaf12) ) return(TRUE);
  58.   return(FALSE);
  59. }
  60.  
  61.  
  62. void Read_Fli_Header(fp,fli_hdr)
  63. FILE *fp;
  64. Fli_Header *fli_hdr;
  65. {
  66.   int i;
  67.  
  68.   fli_hdr->size   = UTIL_Get_LSB_Long(fp);
  69.   fli_hdr->magic  = UTIL_Get_LSB_Short(fp);
  70.   fli_hdr->frames = UTIL_Get_LSB_Short(fp);
  71.   fli_hdr->width  = UTIL_Get_LSB_Short(fp);
  72.   fli_hdr->height = UTIL_Get_LSB_Short(fp);
  73.   fli_hdr->res1   = UTIL_Get_LSB_Short(fp);
  74.   fli_hdr->flags  = UTIL_Get_LSB_Short(fp);
  75.   fli_hdr->speed  = UTIL_Get_LSB_Short(fp);
  76.   fli_hdr->next   = UTIL_Get_LSB_Long(fp);
  77.   fli_hdr->frit   = UTIL_Get_LSB_Long(fp);
  78.   for(i=0;i<102;i++) fgetc(fp);   /* ignore unused part of Fli_Header */
  79.  
  80.   imagex=fli_hdr->width;
  81.   imagey=fli_hdr->height;
  82.   if ( (fli_hdr->magic != 0xaf11) && (fli_hdr->magic != 0xaf12) )
  83.   {
  84.    fprintf(stderr,"imagex=%lx imagey=%lx\n",imagex,imagey);
  85.    fprintf(stderr,"Fli Header Error magic %lx not = 0xaf11\n",fli_hdr->magic);
  86.    TheEnd();
  87.   }
  88. }
  89.  
  90. void Read_Fli_Frame_Header(fp,frame_hdr)
  91. FILE *fp;
  92. Fli_Frame_Header *frame_hdr;
  93. {
  94.   int i;
  95.  
  96.   frame_hdr->size = UTIL_Get_LSB_Long(fp);
  97.   frame_hdr->magic = UTIL_Get_LSB_Short(fp);
  98.   frame_hdr->chunks = UTIL_Get_LSB_Short(fp);
  99.   for(i=0;i<8;i++) fgetc(fp);    /* ignore unused part of Fli_Frame_Header */
  100.  
  101.   DEBUG_LEVEL1 
  102.     fprintf(stderr,"Frame Header size %lx  magic %lx  chunks %ld\n",
  103.         frame_hdr->size,frame_hdr->magic,frame_hdr->chunks);
  104.  
  105.   if (   (frame_hdr->magic != 0xf1fa)
  106.       && (frame_hdr->magic != 0xf100) )
  107.   {
  108.     fprintf(stderr,"Frame_Header Error magic %lx not = 0xf1fa\n",
  109.                             frame_hdr->magic);
  110.     TheEnd();
  111.   }
  112. }
  113.  
  114. void Fli_Read_File(fname,anim_hdr)
  115. char *fname;
  116. ANIM_HDR *anim_hdr;
  117. {
  118.   FILE *fin;
  119.   int i,j,ret;
  120.   ACTION *act;
  121.   UBYTE *pic;
  122.   ULONG pic_size;
  123.   ULONG second_frame;
  124.  
  125.  
  126.   if ( (fin=fopen(fname,"r")) == 0)
  127.   { 
  128.     fprintf(stderr,"can't open Fli File %s for reading\n",fname); 
  129.     TheEnd();
  130.   }
  131.  
  132.   Read_Fli_Header(fin,&fli_hdr);
  133.  
  134.   if (verbose) 
  135.   {
  136.    fprintf(stderr,"Reading FLI File %s\n",fname);
  137.    fprintf(stderr,"   Size  %ldx%ld Frames = %ld\n",fli_hdr.width,
  138.             fli_hdr.height,fli_hdr.frames);
  139.   }
  140.  
  141.   /* Start off with global colormap
  142.    */
  143.   /* NOTE: do better than this */
  144.   imagec = FLI_MAX_COLORS;
  145.   for(i = 0; i < FLI_MAX_COLORS; i++) 
  146.   {
  147.     if ( (i < x11_cmap_size) && (x11_cmap_flag == TRUE) )
  148.     {
  149.       fli_cmap[i].red   = cmap[i].red;
  150.       fli_cmap[i].green = cmap[i].green;
  151.       fli_cmap[i].blue  = cmap[i].blue;
  152.       fli_cmap[i].map   = i;
  153.     }
  154.     else /* for displays with cmaps larger than 256 colors */
  155.     {
  156.       fli_cmap[i].red   = 0;
  157.       fli_cmap[i].green = 0;
  158.       fli_cmap[i].blue  = 0;
  159.       fli_cmap[i].map   = i;
  160.     }
  161.   }
  162.  
  163.   /* Allocate image buffer so deltas may be applied if buffering
  164.    */
  165.   pic_size = imagex * imagey;
  166.  
  167.   if (buff_flag == TRUE)
  168.   {
  169.     pic = (UBYTE *) malloc(pic_size);
  170.     if (pic == 0) TheEnd1("BufferAction: malloc failed");
  171.   }
  172.  
  173.  
  174.   /* in case there isn't a 2nd frame */
  175.   second_frame = action_cnt;
  176.   for(i = 0; i < fli_hdr.frames; i++)
  177.   {
  178.     ULONG fli_time;
  179.     UBYTE *t_pic;
  180.  
  181.     /* in order to loop back to 2nd frame */
  182.     if (i == 1) second_frame = action_cnt;
  183.  
  184.     Read_Fli_Frame_Header(fin, &frame_hdr);
  185.     
  186.     if (frame_hdr.magic == 0xf100)
  187.     {
  188.      int i;
  189.      DEBUG_LEVEL1 
  190.     fprintf(stderr,"FLI 0xf100 Frame: size = %lx\n",frame_hdr.size);
  191.      for(i=0;i<(frame_hdr.size - 16);i++) fgetc(fin);
  192.      if (frame_hdr.size & 0x01) fgetc(fin); 
  193.     }
  194.     else
  195.     if (frame_hdr.chunks==0)  /* this frame is for timing purposes */
  196.     {
  197.       DEBUG_LEVEL1 fprintf(stderr," FLI DELAY %ld\n",fli_hdr.speed);
  198.  
  199.       ACT_Get_Next_Action(&act);
  200.       act->type = ACT_DELAY;
  201.       if (jiffy_flag) act->time = jiffy_flag;
  202.       else act->time = fli_hdr.speed * MS_PER_60HZ;
  203.       act->data = 0;
  204.     }
  205.     else /* this frame has real data in it */
  206.     {
  207.       /* Loop through chunks in the frame
  208.        */
  209.       for(j=0;j<frame_hdr.chunks;j++)
  210.       {
  211.         ULONG chunk_size,chunk_type;
  212.    
  213.         chunk_size = UTIL_Get_LSB_Long(fin);
  214.         chunk_type = UTIL_Get_LSB_Short(fin);
  215.         switch(chunk_type)
  216.         {
  217.           case CHUNK_4:     /* FLI Color with 8 bits RGB */
  218.                  DEBUG_LEVEL1 fprintf(stderr," FLI COLOR(4)\n");
  219.          Read_Fli_COLOR(fin,0);
  220.          break;
  221.  
  222.           case FLI_COLOR:     /* FLI Color with 6 bits RGB */
  223.                  DEBUG_LEVEL1
  224.             fprintf(stderr," FLI COLOR(11)\n");
  225.          Read_Fli_COLOR(fin,2);
  226.          break;
  227.  
  228.           case FLI_LC:
  229.           case FLI_LC7:
  230.           case FLI_BRUN:
  231.           case FLI_COPY:
  232.         {
  233.          UBYTE *chunk_data,kludge;
  234.          
  235.          if ( (chunk_type==FLI_COPY) && (imagex == 320)) kludge = 4;
  236.          else kludge = 6;
  237.              ACT_Get_Next_Action(&act);
  238.          fli_time = (jiffy_flag)?(jiffy_flag)
  239.                     :(fli_hdr.speed * MS_PER_60HZ);
  240.          switch(chunk_type)
  241.          {
  242.           case FLI_LC7:
  243.             DEBUG_LEVEL1 fprintf(stderr," FLI LC(7)\n");
  244.             act->type = ACT_FLI_LC7;
  245.             break;
  246.           case FLI_LC:
  247.             DEBUG_LEVEL1 fprintf(stderr," FLI LC(12)\n");
  248.             act->type = ACT_FLI_LC;
  249.             break;
  250.           case FLI_BRUN:
  251.             DEBUG_LEVEL1 fprintf(stderr," FLI BRUN(15)\n");
  252.             act->type = ACT_FLI_BRUN;
  253.             break;
  254.           case FLI_COPY:
  255.             DEBUG_LEVEL1 fprintf(stderr," FLI COPY(16)\n");
  256.             act->type = ACT_FLI_COPY;
  257.             break;
  258.          }
  259.  
  260.          if (chunk_size > kludge)
  261.          {
  262.             chunk_data = (UBYTE *) malloc( chunk_size-kludge );
  263.             if (chunk_data == 0) TheEnd1("FLI CHUNK: malloc failed");
  264.             ret = fread( chunk_data, (chunk_size-kludge), 1, fin);
  265.             if (ret != 1) TheEnd1("FLI CHUNK: read failed");
  266.          }
  267.          else TheEnd1("FLI CHUNK: invalid chunk size");
  268.  
  269.          if (buff_flag == FALSE)
  270.          {
  271.             act->time = fli_time;
  272.             act->data = chunk_data;
  273.          }
  274.                  else /* buffer it up */
  275.          {
  276.            ULONG xpos,ypos,xsize,ysize,new_size;
  277.  
  278.            switch(chunk_type)
  279.            {
  280.              case FLI_LC7:
  281.             Decode_Fli_LC7(fli_cmap,chunk_data, pic, 
  282.                 &xpos,&ypos,&xsize,&ysize,FALSE);
  283.             break;
  284.              case FLI_LC:
  285.             Decode_Fli_LC(fli_cmap,chunk_data, pic, 
  286.                 &xpos,&ypos,&xsize,&ysize,FALSE);
  287.             break;
  288.              case FLI_BRUN:
  289.             Decode_Fli_BRUN(fli_cmap,chunk_data,pic,FALSE);
  290.             xpos = ypos = 0; xsize = imagex; ysize = imagey;
  291.             break;
  292.              case FLI_COPY:
  293.             if ( (chunk_size-kludge) > pic_size)
  294.             {
  295.              fprintf(stderr,"chunk_size = %lx pic_size=%lx\n",
  296.                 chunk_size,pic_size);
  297.              TheEnd1("FLI COPY: invalid chunk_size");
  298.             }
  299.             memcpy((char *)pic,(char *)chunk_data,(chunk_size-6));
  300.             xpos = ypos = 0; xsize = imagex; ysize = imagey;
  301.             break;
  302.            }
  303.            new_size = xsize * ysize;
  304.            t_pic = (UBYTE *) malloc(new_size * x11_bytes_pixel);
  305.            if (t_pic == 0) TheEnd1 ("FLI BUFF CHUNK: malloc failed");
  306.            UTIL_Sub_Image(t_pic,pic,xsize,ysize,xpos,ypos,imagex,1);
  307.            ACT_Setup_Mapped(act,fli_time,t_pic,fli_cmap,imagec,
  308.             xpos,ypos,xsize,ysize,FALSE,0);
  309.            free(chunk_data);
  310.          } /* end of buffer */
  311.         }
  312.         break;
  313.  
  314.           case FLI_BLACK:
  315.         {
  316.                  DEBUG_LEVEL1 fprintf(stderr," FLI BLACK(13)\n");
  317.          if (chunk_size > 6) 
  318.                        TheEnd1("Read_Fli_BLACK different than expected\n");
  319.  
  320.              ACT_Get_Next_Action(&act);
  321.          fli_time = (jiffy_flag)?(jiffy_flag)
  322.                     :(fli_hdr.speed * MS_PER_60HZ);
  323.  
  324.                  if (buff_flag == TRUE)
  325.          {
  326.                    t_pic = (UBYTE *) malloc( pic_size * x11_bytes_pixel);
  327.                    if (t_pic == 0) TheEnd1("Buff FLI BLACK: malloc failed");
  328.             /* create black image */
  329.                    memset(t_pic,0x00,(pic_size * x11_bytes_pixel) ); 
  330.             /* clear pic buffer */
  331.                    memset(pic,0x00,pic_size);
  332.            ACT_Setup_Mapped(act,fli_time,t_pic,fli_cmap,imagec,
  333.             0,0,imagex,imagey,TRUE,0);
  334.          }
  335.          else
  336.          {
  337.            act->type = ACT_FLI_BLACK;
  338.             act->time = fli_time;
  339.             act->data = 0;
  340.          }
  341.         }
  342.         break;
  343.           case FLI_MINI:
  344.         {
  345.           int i;
  346.           DEBUG_LEVEL1 fprintf(stderr," FLI MINI(18) ignored.\n");
  347.           for(i=0;i<(chunk_size-6);i++) fgetc(fin);
  348.           if (chunk_size & 0x01) fgetc(fin); 
  349.         }
  350.         break;
  351.  
  352.            default: 
  353.              {
  354.                int i;
  355.            fprintf(stderr,"FLI Unsupported Chunk: type = %lx size=%lx\n",
  356.                     chunk_type,chunk_size);
  357.                for(i=0;i<(chunk_size-6);i++) fgetc(fin);
  358.                if (chunk_size & 0x01) fgetc(fin); 
  359.              }
  360.              
  361.          break;
  362.         } /* end of switch */
  363.       } /* end of chunks is frame */
  364.     } /* end of not Timing Frame */
  365.   } /* end of frames in file */
  366.   if ( (buff_flag) && (pic != 0) ) free(pic);        
  367.   fclose(fin);
  368.  
  369.   {
  370.     ULONG action_number;
  371.  
  372.     action_number = action_cnt - action_start;
  373.     anim_hdr->frame_lst =
  374.              (int *)malloc(sizeof(int) * (action_number+1));
  375.     if (anim_hdr->frame_lst == NULL)
  376.         TheEnd1("FLI_ANIM: couldn't malloc for frame_lst\0");
  377.     for(i=0; i < action_number; i++)
  378.         anim_hdr->frame_lst[i]=action_start+i;
  379.     anim_hdr->frame_lst[action_number] = -1;
  380.     anim_hdr->loop_frame = 0;
  381.     /* second_frame - action_start; */
  382.     anim_hdr->last_frame = action_number-1;
  383.   }
  384.  
  385. }
  386.  
  387.  
  388. /*
  389.  * Routine to Decode a Fli BRUN chunk
  390.  */
  391. void Decode_Fli_BRUN(map,data,image_out,map_flag)
  392. ColorReg *map;
  393. unsigned char *data,*image_out;
  394. ULONG map_flag;
  395. {
  396.   ULONG i,j,k,packets,size,x,offset;
  397.  
  398.   for(i=0; i<imagey; i++)
  399.   {
  400.     offset = i * imagex;
  401.     packets = *data++;
  402.  
  403.     x=0;
  404.     for(j= 0; j < packets; j++)
  405.     {
  406.       size = *data++;
  407.       if (size & 0x80)         /* size < 0 so there is -size unique bytes */
  408.       {
  409.         size = 256-size; 
  410.         if (map_flag == TRUE)
  411.         {
  412.           if (x11_bytes_pixel == 4)
  413.             for(k=x;k<(x+size);k++)
  414.                 ((ULONG *)(image_out))[k+offset] = (ULONG)(map[*data++].map);
  415.           else if (x11_bytes_pixel == 2)
  416.             for(k=x;k<(x+size);k++)
  417.                 ((USHORT *)(image_out))[k+offset] = (USHORT)(map[*data++].map);
  418.           else
  419.             for(k=x;k<(x+size);k++)
  420.                 ((UBYTE *)(image_out))[k+offset] = (UBYTE)(map[*data++].map);
  421.         }
  422.         else
  423.         {
  424.           for(k=x;k<(x+size);k++)
  425.                 ((UBYTE *)(image_out))[k+offset] = (UBYTE)(*data++);
  426.         }
  427.  
  428.         x += size;   
  429.       }
  430.       else                     /* size is pos repeat next byte size times */
  431.       {
  432.         ULONG d;
  433.         d = *data++;
  434.         if (map_flag == TRUE)
  435.         {
  436.           if (x11_bytes_pixel == 4)
  437.             for(k=x;k<(x+size);k++)
  438.                 ((ULONG *)(image_out))[k+offset] = (ULONG)(map[d].map);
  439.           else if (x11_bytes_pixel == 2)
  440.              for(k=x;k<(x+size);k++)
  441.                 ((USHORT *)(image_out))[k+offset] = (USHORT)(map[d].map);
  442.           else
  443.              for(k=x;k<(x+size);k++)
  444.                 ((UBYTE *)(image_out))[k+offset] = (UBYTE)(map[d].map);
  445.         }
  446.         else
  447.         {
  448.           for(k=x;k<(x+size);k++)
  449.                 ((UBYTE *)(image_out))[k+offset] = (UBYTE)(d);
  450.         }
  451.         x+=size;   
  452.       }
  453.     } /* end of packets per line */
  454.   } /* end of line */
  455. }
  456.  
  457. /*
  458.  * Routine to Decode an Fli LC chunk
  459.  */
  460. void Decode_Fli_LC(map,data,image_out,xpos,ypos,xsize,ysize,map_flag)
  461. ColorReg *map;
  462. unsigned char *data,*image_out;
  463. ULONG *xpos,*ypos,*xsize,*ysize,map_flag;
  464. {
  465.   ULONG i,j,k,packets,size,x,offset;
  466.   ULONG start,lines,skip,minx,maxx;
  467.  
  468.   start = *data++; start |= *data++ << 8;  /* lines to skip */
  469.   lines = *data++; lines |= *data++ << 8;  /* number of lines */
  470.  
  471.   minx = imagex; 
  472.   maxx = 0;
  473.  
  474.   for(i=start;i<(start+lines);i++)
  475.   {
  476.     offset = i * imagex;
  477.     packets = *data++;
  478.  
  479.     x=0;
  480.     for(j=0;j<packets;j++)
  481.     {
  482.       skip = *data++;   /* this is the skip count */
  483.       size = *data++;
  484.  
  485.       if (j==0) if (skip < minx) minx = skip;
  486.       x+=skip;
  487.       if (size==0) 
  488.       {
  489. /*
  490.         size = *data++;
  491.         fprintf(stderr,"size==0 what to we do? next is %ld\n",size);
  492.         TheEnd();
  493. */
  494.       }
  495.       else if (size & 0x80) /* next byte repeated -size times */
  496.       {
  497.         ULONG d;
  498.         size = 256-size; 
  499.         d = *data++;
  500.     if (map_flag == TRUE)
  501.         {
  502.       if (x11_bytes_pixel == 4)
  503.             for(k=x;k<(x+size);k++) 
  504.         ((ULONG *)(image_out))[k+offset] = (ULONG)(map[d].map);
  505.       else if (x11_bytes_pixel == 2)
  506.              for(k=x;k<(x+size);k++) 
  507.         ((USHORT *)(image_out))[k+offset] = (USHORT)(map[d].map);
  508.       else
  509.              for(k=x;k<(x+size);k++) 
  510.         ((UBYTE *)(image_out))[k+offset] = (UBYTE)(map[d].map);
  511.         }
  512.         else
  513.         {
  514.           for(k=x;k<(x+size);k++) 
  515.         ((UBYTE *)(image_out))[k+offset] = (UBYTE)(d);
  516.         }
  517.         x+=size;   
  518.       }
  519.       else /* size is pos */
  520.       {
  521.         if (map_flag == TRUE)
  522.         {
  523.           if (x11_bytes_pixel == 4)
  524.             for(k=x;k<(x+size);k++) 
  525.         ((ULONG *)(image_out))[k+offset] = (ULONG)(map[*data++].map);
  526.           else if (x11_bytes_pixel == 2)
  527.             for(k=x;k<(x+size);k++) 
  528.         ((USHORT *)(image_out))[k+offset] = (USHORT)(map[*data++].map);
  529.           else
  530.             for(k=x;k<(x+size);k++) 
  531.         ((UBYTE *)(image_out))[k+offset] = (UBYTE)(map[*data++].map);
  532.         }
  533.         else
  534.         {
  535.           for(k=x;k<(x+size);k++) 
  536.         ((UBYTE *)(image_out))[k+offset] = (UBYTE)(*data++);
  537.         }
  538.  
  539.         x+=size;   
  540.       }
  541.     } /* end of packets per line */
  542.     if (x > maxx) maxx = x;
  543.   } /* end of line */
  544.  
  545.   if (optimize_flag == TRUE)
  546.   {
  547.    *ypos = start;
  548.    *ysize = lines;
  549.    *xpos = minx;
  550.    if (maxx > imagex) maxx=imagex;
  551.    if (maxx > minx) *xsize = maxx - minx;
  552.    else *xsize = imagex - minx;
  553.   }
  554.   else
  555.   {
  556.    *ypos = 0;
  557.    *ysize = imagey;
  558.    *xpos = 0;
  559.    *xsize = imagex;
  560.   }
  561.  
  562.   DEBUG_LEVEL1 fprintf(stderr,"      LC: xypos=<%ld %ld> xysize=<%ld %ld>\n",
  563.                         *xpos,*ypos,*xsize,*ysize);
  564.  
  565. }
  566.  
  567.  
  568. /*
  569.  * Routine to read an Fli COLOR chunk
  570.  */
  571. void Read_Fli_COLOR(fin,color_shift)
  572. FILE *fin;
  573. ULONG color_shift;
  574. {
  575.  ULONG k,l,c_index,packets,skip,colors,cnt;
  576.  
  577.  packets = UTIL_Get_LSB_Short(fin);
  578.  c_index = 0;
  579.  
  580.  DEBUG_LEVEL1 fprintf(stderr,"   packets = %ld\n",packets);
  581.  cnt=2;
  582.  for(k=0;k<packets;k++)
  583.  {
  584.   skip = fgetc(fin);
  585.   colors=fgetc(fin);
  586.   DEBUG_LEVEL1 fprintf(stderr,"      skip %ld colors %ld\n",skip,colors);
  587.   cnt+=2;
  588.   if (colors==0) colors=FLI_MAX_COLORS;
  589.   if ( (colors > x11_cmap_size) &&
  590.        (x11_display_type == PSEUDO_COLOR) )
  591.   {
  592.    fprintf(stderr,"FLI has %ld colors and the display only supports %ld.\n",
  593.          colors,x11_cmap_size);
  594.    TheEnd();
  595.   }
  596.   c_index += skip;
  597.   for(l = 0; l < colors; l++)
  598.   {
  599.    fli_cmap[c_index].red   = fgetc(fin) << color_shift;
  600.    fli_cmap[c_index].green = fgetc(fin) << color_shift;
  601.    fli_cmap[c_index].blue  = fgetc(fin) << color_shift;
  602.    DEBUG_LEVEL5 fprintf(stderr,"         %ld)  <%lx %lx %lx>\n", 
  603.           l,fli_cmap[l].red, fli_cmap[l].green,fli_cmap[l].blue);
  604.    c_index++;
  605.   } /* end of colors */
  606.   cnt+= 3 * colors;
  607.  } /* end of packets */
  608.  if (cnt&0x01) fgetc(fin);  /* read pad byte if needed */
  609.  
  610.  ACT_Setup_CMAP(fli_cmap,FLI_MAX_COLORS,&k,CMAP_DIRECT);
  611.  
  612. }
  613.  
  614. /*
  615.  * Routine to Decode an Fli LC chunk
  616.  */
  617. void Decode_Fli_LC7(map,data,image_out,xpos,ypos,xsize,ysize,map_flag)
  618. ColorReg *map;
  619. UBYTE *data,*image_out;
  620. ULONG *xpos,*ypos,*xsize,*ysize,map_flag;
  621. {
  622.   ULONG i,j,x,y;
  623.   ULONG packets,blocks,xoff,cnt,tmp_data0,tmp_data1;
  624.   ULONG minx,maxx,miny;
  625.   UBYTE *ptr;
  626.   
  627.  
  628.   minx = imagex;
  629.   maxx = 0;
  630.   miny = imagey;
  631.  
  632.   ptr = image_out;
  633.   y = 0;
  634.   packets = *data++; packets |= *data++ << 8;  /* # of packets */
  635.  
  636.   DEBUG_LEVEL5 fprintf(stderr,"pkts=%ld\n",packets);
  637.  
  638.   for(i=0; i < packets; i++)
  639.   {
  640.    
  641.     blocks = *data++; blocks |= *data++ << 8; 
  642.  
  643.     DEBUG_LEVEL5 fprintf(stderr,"     %ld) ",i);
  644.  
  645.     if (blocks & 0x8000)  /* neg lines to jump */
  646.     {
  647.       blocks = 0x10000 - blocks;
  648.       y += blocks;
  649.       DEBUG_LEVEL5 fprintf(stderr,"     yskip %ld",blocks);
  650.       blocks = *data++; blocks |= *data++ << 8;
  651.     }
  652.     DEBUG_LEVEL5 fprintf(stderr,"     blocks = %ld\n",blocks);
  653.  
  654.     if (optimize_flag == TRUE) if (y < miny) miny = y;
  655.  
  656.     ptr  = (UBYTE *)( (ULONG)(image_out) + y*imagex*x11_bytes_pixel);
  657.     x = 0;
  658.  
  659.     for(j=0; j < blocks; j++)
  660.     {
  661.       xoff = (ULONG) *data++;  /* x offset */
  662.       cnt  = (ULONG) *data++;  /* halfword count */
  663.       ptr += (xoff * x11_bytes_pixel);
  664.       x += xoff;
  665.  
  666.       DEBUG_LEVEL5 
  667.         fprintf(stderr,"          %ld) xoff %lx  cnt = %lx",j,xoff,cnt);
  668.  
  669.       if (cnt & 0x80)
  670.       {
  671.         cnt = 256 - cnt;
  672.         DEBUG_LEVEL5 fprintf(stderr,"               NEG %ld\n",cnt);
  673.         if (optimize_flag == TRUE)
  674.         {  
  675.           if (x < minx) minx = x;
  676.           x += (cnt << 1);
  677.           if (x > maxx) maxx = x;
  678.         }
  679.  
  680.     if (map_flag == TRUE)
  681.         {
  682.           tmp_data0 = map[*data++].map;
  683.           tmp_data1 = map[*data++].map;
  684.           if (x11_bytes_pixel == 4)
  685.       { 
  686.         ULONG *ulp = (ULONG *)ptr;
  687.             while(cnt--) { *ulp++ = (ULONG)tmp_data0;
  688.                *ulp++ = (ULONG)tmp_data1; }
  689.         ptr = (UBYTE *)ulp;
  690.           }
  691.           else if (x11_bytes_pixel == 2)
  692.       { 
  693.         USHORT *usp = (USHORT *)ptr;
  694.         while(cnt--) { *usp++ = (USHORT)tmp_data0;
  695.                *usp++ = (USHORT)tmp_data1; }
  696.         ptr = (UBYTE *)usp;
  697.           }
  698.           else
  699.             while(cnt--) { *ptr++ = (UBYTE)tmp_data0;
  700.                            *ptr++ = (UBYTE)tmp_data1; }
  701.     }
  702.     else
  703.     {
  704.           tmp_data0 = *data++;
  705.           tmp_data1 = *data++;
  706.           while(cnt--) { *ptr++ = (UBYTE)tmp_data0;
  707.                          *ptr++ = (UBYTE)tmp_data1; }
  708.     }
  709.  
  710.       }
  711.       else
  712.       {   /* cnt is number of unique pairs of bytes */
  713.         DEBUG_LEVEL5 fprintf(stderr,"               POS %ld\n",cnt);
  714.         if (optimize_flag == TRUE)
  715.         {
  716.           if (cnt == 1)  /* potential NOPs just to move x */
  717.           {
  718.             if ( (*ptr != *data) || (ptr[1] != data[1]) )  
  719.             {
  720.               if (x < minx) minx = x; 
  721.               x += (cnt << 1);
  722.               if (x > maxx) maxx = x;
  723.             }
  724.           }
  725.       else
  726.           {
  727.             if (x < minx) minx = x; 
  728.             x += (cnt << 1);
  729.             if (x > maxx) maxx = x;
  730.           }
  731.         }
  732.         if (map_flag == TRUE)
  733.         {
  734.           if (x11_bytes_pixel == 4)
  735.       { 
  736.         ULONG *ulp = (ULONG *)ptr;
  737.         while(cnt--) { *ulp++ = (ULONG)map[*data++].map;
  738.                            *ulp++ = (ULONG)map[*data++].map; }
  739.         ptr = (UBYTE *)ulp;
  740.           }
  741.           else if (x11_bytes_pixel == 2)
  742.       { 
  743.         USHORT *usp = (USHORT *)ptr;
  744.         while(cnt--) { *usp++ = (USHORT)map[*data++].map;
  745.                *usp++ = (USHORT)map[*data++].map; }
  746.         ptr = (UBYTE *)usp;
  747.           }
  748.           else
  749.              while(cnt--) { *ptr++ = (UBYTE)map[*data++].map;
  750.                 *ptr++ = (UBYTE)map[*data++].map; }
  751.         }
  752.         else
  753.              while(cnt--) { *ptr++ = (UBYTE) *data++;
  754.                 *ptr++ = (UBYTE) *data++; }
  755.  
  756.       } 
  757.     } /* (j) end of blocks */
  758.     y++;
  759.   } /* (i) end of packets */
  760.  
  761. DEBUG_LEVEL3
  762.  fprintf(stderr,"      LC: minx miny (%ld %ld), maxx maxy (%ld %ld)\n",
  763.      minx,miny,maxx,y);
  764.  
  765.   if (optimize_flag == TRUE)
  766.   {
  767.     if (minx >= imagex) minx = 0; 
  768.     if (miny >= imagey) miny = 0; 
  769.  
  770.     *xpos = minx;
  771.     *ypos = miny;
  772.  
  773.     if (maxx > minx) *xsize = maxx - minx + 2;
  774.     else             *xsize = imagex - minx;
  775.  
  776.     if (y > miny) *ysize = y - miny + 1;
  777.     else          *ysize = imagey - miny;
  778.   }
  779.   else
  780.   {
  781.     *xpos = 0;
  782.     *ypos = 0;
  783.     *xsize = imagex;
  784.     *ysize = imagey;
  785.   }
  786.  
  787.   DEBUG_LEVEL1 fprintf(stderr,"      LC: xypos=<%ld %ld> xysize=<%ld %ld>\n",
  788.          *xpos,*ypos,*xsize,*ysize);
  789.  
  790. }
  791.  
  792.  
  793.